package array;

public class ArrayStack<T> implements StackADT<T>{

    private final int DEFAULT_SIZE=1;

    private T[] stack;
    private int top;
    //创建空栈
    public ArrayStack() {
        top=0;
        stack= (T[]) new Object[DEFAULT_SIZE];
    }
    //创建size大小的栈
    public ArrayStack(int size) {
        top=0;
        stack= (T[]) new Object[size];
    }

    @Override
    public void push(T t) {
        //如果栈满
        if (stack.length==size()){
            T[] newStack = expandStack(stack);
            //释放原数组，改变指向新内存空间
            stack=newStack;
        }

        stack[top++]=t;
    }
    //为栈进行2倍容积扩容
    private T[] expandStack(T[] oldStack) {
        T[] newStack=(T[]) new Object[oldStack.length*2];
        for (int i = 0; i <oldStack.length ; i++) {
            newStack[i]=oldStack[i];
        }

        return newStack;
    }

    @Override
    public T pop() {
        if (isEmpty()) throw new RuntimeException("栈空无法pop");
        top--;
        T result = stack[top];
        //设置栈顶为空值
        stack[top]=null;
        return result;
    }

    @Override
    public T peek() {
        if (isEmpty()) throw new RuntimeException("栈空无法pop");
        return stack[top-1];
    }

    @Override
    public boolean isEmpty() {
        return top==0;
    }

    @Override
    public int size() {
        return top;
    }

    @Override
    public void print() {
        if (size()==0) {
            System.out.println("[]");
            return;
        }
        StringBuilder builder = new StringBuilder("[");
        for (T ele : stack) {
            if (ele==null) break;
            builder.append(ele);
            builder.append(",");
        }
        builder.replace(builder.length()-1, builder.length(), "]");
        System.out.println(builder);
    }

    public static class Test{
        public static void main(String[] args) {
            ArrayStack<Integer> testStack = new ArrayStack<>();
            testStack.push(11);
            testStack.push(22);
            testStack.push(33);
            System.out.println(testStack.pop());
            testStack.print();
            System.out.println(testStack.peek());
            System.out.println(testStack.size());
        }
    }
}
